图像语义分割

您所在的位置:网站首页 图像分类 上下文 图像语义分割

图像语义分割

2024-07-10 04:23| 来源: 网络整理| 查看: 265

Context Prior for Scene Segmentation-设计注意力机制模块加入上下文先验信息–关键创新点代码复现-tensorflow2.x、keras。

论文:Context Prior for Scene Segmentation 代码github:暂未开源 最近在研究注意力机制与先验信息,查阅到这篇论文,但是暂未开源代码,便根据对论文内容的理解复现论文方法,使用TensorFlow2.x版本,基于Keras编写代码

论文介绍 摘要

最近的语义分割工作广泛探索了上下文相关性,以实现更准确的细分结果。但是,大多数方法很少区分不同类型的上下文依赖项,这可能会有损场景理解。在这项工作中,我们直接监督特征聚合以清楚地区分类内和类间上下文信息。具体来说,我们在Affinity Loss监督下开发出上下文先验。 给定输入图像和相应的gt,Affinity Loss将构建理想的类似的特征图,以监督上下文先验的学习。 所学习的上下文先验提取属于同一类别的像素,而相反的先验则专注于不同类别的像素。 通过嵌入到传统的深度CNN中,提出的上下文先验层可以选择性地捕获类内和类间上下文相关性,从而实现可靠的特征表示。 为了验证有效性,我们设计了有效的上下文先验网络(CPNet)。大量的定量和定性评估表明,所提出的模型与最新的语义分割方法相比具有良好的表现。 更具体地说,我们的算法在ADE20K上达到46.3%的mIoU,在PASCAL-Context上达到53.9%的mIoU,在Cityscapes上达到81.3%的mIoU【参考博客】

关键点

CPlayer 提出以上模块,说的是通过生成的Ideal Affinity Map向网络中加入像素值的先验信息去监督网络对类内和内间学习(我的理解就是相当于把原标签转为另一种表达方式与网络的某一层输出的特征图求损失,其实相比于其他分割网络最后输入的损失计算,换汤不换药!!!)。该模块可加在任意主干网络后,用于对主干网络生成的特征图进行再一次的特征提取。

开整代码

导入依赖包

from tensorflow import keras from tensorflow.keras import layers import tensorflow.keras.backend as K from CoordConv2 import Coord_Conv2d import tensorflow as tf Aggregation模块

在这里插入图片描述 把3X3的卷积核分成3X1和1X3两个,效果相似,参数计算大量减少。

def Aggregation(x, num_classes): x = layers.Conv2D(filters=num_classes, kernel_size=3, padding='same')(x) x = layers.BatchNormalization()(x) x = layers.Activation('relu')(x) x1 = layers.DepthwiseConv2D(kernel_size=(1, 3), padding='same')(x) x1 = layers.DepthwiseConv2D(kernel_size=(3, 1), padding='same')(x1) x2 = layers.DepthwiseConv2D(kernel_size=(3, 1), padding='same')(x) x2 = layers.DepthwiseConv2D(kernel_size=(1, 3), padding='same')(x2) x = layers.Add()([x1, x2]) x = layers.BatchNormalization()(x) x = layers.Activation('relu')(x) return x CP过程

在这里插入图片描述

def CP(x): B, H, W, C = x.shape x_origon = x x_origon = tf.reshape(x_origon, [-1, H*W, C]) x = layers.Conv2D(filters=H*W, kernel_size=1, padding='same')(x) x = layers.BatchNormalization()(x) x = layers.Activation('sigmoid')(x) x = tf.reshape(x, [-1, H*W, H*W], name='out1') # 论文中P,Context Prior Map x1 = tf.matmul(x, x_origon) x1 = tf.reshape(x1, [-1, H, W, C]) x2 = tf.matmul(tf.ones_like(x)-x, x_origon) x2 = tf.reshape(x2, [-1, H, W, C]) return x, x1, x2 CPModule

在这里插入图片描述

def CPModule(x, num_classes): x1 = Aggregation(x, num_classes) x2, x3, x4 = CP(x1) output = layers.Concatenate()([x, x3, x4]) return x2, output

x2用于论文提出的AffinityLoss计算,output用于普通的softmax损失计算

Affinity Loss loss_1

在这里插入图片描述

loss_binary = keras.losses.binary_crossentropy(Ideal_Affinity_Map, Context_Prior_Map) loss_2

在这里插入图片描述

Tp = K.log(K.sum(tf.multiply(Ideal_Affinity_Map, Context_Prior_Map), axis=1) / (K.sum(Context_Prior_Map, axis=1)+K.epsilon())+K.epsilon()) Tr = K.log(K.sum(tf.multiply(Ideal_Affinity_Map, Context_Prior_Map), axis=1) / (K.sum(Ideal_Affinity_Map, axis=1)+K.epsilon()) + K.epsilon()) Tj = K.log((K.sum((1.0-Ideal_Affinity_Map)*(1.0-Context_Prior_Map), axis=1)+K.epsilon())/(K.sum(1.0-Ideal_Affinity_Map, axis=1)+K.epsilon())+K.epsilon()) loss = -K.mean(T1+T2+T3) 总损失

在这里插入图片描述

loss+loss_binary 代码汇总

在这里插入图片描述 Ideal Affinity Map的生成论文中是这样描述的 在这里插入图片描述 对于DownSample操作并没有清除的说明用的是什么方法,因此我这儿采用的是多次最大值池化,由于我的标签本就是ONE-HOT标签,所以就不存在论文中提及的one-hot encoding操作。具体标签制作详见我的另一篇博客。 由于我的主干网络输出的特征图是32X32大小,直接将标签降到特征图大小会丢掉很多目标特征(所以对原论文说的把标签图下采样到特征图尺寸是否保留目标的特征信息持怀疑态度,或者作者使用了巧妙的下采样方式就另说了),经试验证明,在我使用的标签图中,下采样到128X128大小,目标的特征信息不会损失。但是实验使用cpu做的,[128X128, 128X128]与[128X128, 128X128]的矩阵运算算不了,所以实验采用的是把标签下采样到64X64大小。原标签尺寸为512X512 使用tf.image中的resize函数下采样可避免特征丢失问题!!

def Affinity_loss(y_true, y_pred): y_true_down = tf.image.resize(y_true, (256, 256), methord=tf.image.ResizeMethord.NEAREST_NEIGHBOR) y_true_down = y_true_down = tf.image.resize(y_true_down , (128, 128), methord=tf.image.ResizeMethord.NEAREST_NEIGHBOR) y_true_down = y_true_down = tf.image.resize(y_true_down , (64, 64), methord=tf.image.ResizeMethord.NEAREST_NEIGHBOR) y_true_down = y_true_down = tf.image.resize(y_true_down , (32, 32), methord=tf.image.ResizeMethord.NEAREST_NEIGHBOR) B_down, H_down, W_down, C_down = y_true_down.shape y_true_down = tf.reshape(y_true_down, [-1, H_down*W_down, C_down]) Ideal_Affinity_Map = tf.matmul(y_true_down, tf.transpose(y_true_down, [0, 2, 1])) Ideal_Affinity_Map = tf.cast(Ideal_Affinity_Map, dtype=tf.float32) Context_Prior_Map = tf.cast(y_pred, dtype=tf.float32) loss_binary = keras.losses.binary_crossentropy(Ideal_Affinity_Map, Context_Prior_Map) T1 = K.log(K.sum(tf.multiply(Ideal_Affinity_Map, Context_Prior_Map), axis=1) / (K.sum(Context_Prior_Map, axis=1)+K.epsilon())+K.epsilon()) T2 = K.log(K.sum(tf.multiply(Ideal_Affinity_Map, Context_Prior_Map), axis=1) / (K.sum(Ideal_Affinity_Map, axis=1)+K.epsilon()) + K.epsilon()) T3 = K.log((K.sum((1.0-Ideal_Affinity_Map)*(1.0-Context_Prior_Map), axis=1)+K.epsilon())/(K.sum(1.0-Ideal_Affinity_Map, axis=1)+K.epsilon())+K.epsilon()) loss = -K.mean(T1+T2+T3) return loss+loss_binary Context_Prior_Map 和 Ideal_Affinity_Map Context_Prior_Map Context_Prior_Map Ideal_Affinity_Map

Ideal_Affinity_Map

总结

总的来说,对上下文先验矩阵Ideal_Affinity_Map的预测还是比较接近论文贴出的结果

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3